package com.swedne.test;


import java.util.TreeSet;

public class QrHelper {
    public static String secretKey = "378DFDF42B029488575B88FA3C2BB49E";
    public static String encryptedStr = "A51702378DFDF52D61CD53195B8DFB392BA48E378DFDF42B15";

    private static class QrResult {
        private boolean isSuccess;
        private int floor;

        public boolean isSuccess() {
            return isSuccess;
        }

        public void setSuccess(boolean success) {
            isSuccess = success;
        }

        public int getFloor() {
            return floor;
        }

        public void setFloor(int floor) {
            this.floor = floor;
        }
    }


    public static void main(String[] args) {
        boolean result = parseContent(decryption(encryptedStr), 1, 3, 4, 0);
        System.out.println(result);
    }

    public static int bytesToInt(byte[] a) {
        int ans = 0;
        for (int i = 0; i < 4; i++) {
            ans <<= 8;
            ans |= (a[3 - i] & 0xff);
            /* 这种写法会看起来更加清楚一些：
            int tmp=a[3-i];
            tmp=tmp&0x000000ff;
            ans|=tmp;*/
        }
        return ans;
    }

    public static byte[] decryption(String hexStr) {
        byte[] qrBytes = hex2Bytes(hexStr);
        printHexString(qrBytes, "scanQr");
        System.out.println("hexStr length=" + qrBytes.length);
        byte[] secretKeyBytes = hex2Bytes(secretKey);
        if (qrBytes.length > 3) {
            //开始位：A5
            if (qrBytes[0] != (byte) 0xA5) {
                return null;
            }
            byte[] encryptBytes = new byte[qrBytes.length - 3];
            System.arraycopy(qrBytes, 3, encryptBytes, 0, encryptBytes.length);
            printHexString(encryptBytes, "encryptBytes");
            int encryptLength = encryptBytes.length;
            int loop = 0;
            int start = 0;
            while (encryptLength > 0) {
                if (encryptLength > 16) {
                    loop = 16;
                } else {
                    loop = encryptLength;
                }
                for (int i = 0; i < loop; i++) {
                    encryptBytes[i + start] = (byte) (encryptBytes[i + start] ^ secretKeyBytes[i]);
                }
                start += loop;
                encryptLength = encryptLength - loop;
            }
            printHexString(encryptBytes, "decryptBytes");
            return encryptBytes;

        }
        return null;
    }

    public static boolean parseContent(byte[] bytes, int mode, int b, int u, int index) {
        if (bytes == null || bytes.length < 20) {
            System.out.println("result = bytes error");
            return false;
        }
        byte[] ss = new byte[4];
        System.arraycopy(bytes, 5, ss, 0, 4);
        printHexString(ss, "time");
        long time = (bytes[5] & 0XFFL) << 24 | (bytes[6] & 0XFFL) << 16 | (bytes[7] & 0XFFL) << 8 | bytes[8] & 0XFFL;
        //启动时间
        System.out.println("time=" + time);
        //有效时间 min
        int persistence = (bytes[9] & 0xFF) << 8 | bytes[10] & 0xFF;
        System.out.println("persistence=" + persistence);
        if (System.currentTimeMillis() / 1000L < time || System.currentTimeMillis() / 1000L - time > persistence * 60) {
            System.out.println("result = time error");
            return false;
        }

        //楼层表
        int floor = bytes[12] & 0xFF;
        System.out.println("floor=" + floor);
        //单元门口机
        if (mode == 1) {
            //门禁机权限
            byte[] accessPermission = new byte[]{bytes[13], bytes[14], bytes[15]};
            String accessStr = printHexString(accessPermission, "accessStr").replace(" ", "");
            char[] chars = accessStr.toCharArray();
            StringBuilder sb = new StringBuilder();
            sb.append(chars[0]).append(chars[1]).append(chars[2]);
            int build = Integer.parseInt(sb.toString());
            System.out.println("build=" + build);
            sb.setLength(0);
            sb.append(chars[3]).append(chars[4]);
            int unit = Integer.parseInt(sb.toString().trim());
            System.out.println("unit=" + unit);
            return build == b && unit == u;
        } else {
            //门禁机权限
            byte[] accessPermission = new byte[]{bytes[13], bytes[14], bytes[15]};
            byte[] accessByte = new byte[8];
            System.arraycopy(bytes, 13, accessByte, 0, bytes.length);
            String accessStr = printHexString(accessPermission, "accessStr").replace(" ", "");
            char[] chars = accessStr.toCharArray();
            TreeSet<Character> characters = new TreeSet<>();
            for (char item : chars) {
                characters.add(item);
            }
            for (Character item : characters) {
                System.out.println("index=" + item);
            }
            char i = (char) ('0' + index);
            System.out.println("currentIndex=" + i);

            if (characters.contains(new Character(i))) {
                return true;
            }
        }
        return false;
    }

    public static void checkSum(byte[] bytes, int len) {
        byte sum = 0;
        for (int i = 0; i < bytes.length - 1; i++) {
            sum += bytes[i];
        }
    }

    public static byte[] hex2Bytes(String hexString) {
        byte[] arrB = hexString.getBytes();
        int iLen = arrB.length;
        System.out.println("iLen=" + iLen);
        byte[] arrOut = new byte[iLen / 2];
        System.out.println("iLen2=" + arrOut.length);
        String strTmp = null;
        try {
            for (int i = 0; i < iLen; i += 2) {
                if (i + 2 > iLen) {
                    break;
                }
                strTmp = new String(arrB, i, 2);
                arrOut[(i / 2)] = ((byte) Integer.parseInt(strTmp, 16));
            }
        } catch (Exception ex) {

        }

        return arrOut;
    }

    public static String printHexString(byte[] b) {
        return printHexString(b, null);
    }

    public static String printHexString(byte[] b, String logIntroduce) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < b.length; i++) {
            String hex = Integer.toHexString(b[i] & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            sb.append(hex.toUpperCase() + " ");
        }
        System.out.println("zrz=///" + logIntroduce + "=" + sb.toString());
        return sb.toString();
    }
}
